/*
 * CommunicationRobot11.cpp
 *
 *  Created on: 15/11/2013
 *      Author: gonzalo
 */

#include "CommunicationRobot11.h"
#include "../capa_servicios_distribuidos/QueueLauncher.h"
#include "../distributed_semaphore/comun/DSEMCommon.h"

namespace middleware {

const std::string CommunicationRobot11::ROBOT11_SEM_PATH = "/tmp/robot11";
const std::string CommunicationRobot11::ROBOT11_SHMEM_PATH = "/tmp/robot11mem";
const char CommunicationRobot11::ROBOT11_SHMEM_KEY_IZQ = 'i';
const char CommunicationRobot11::ROBOT11_SHMEM_KEY_DER = 'd';

CommunicationRobot11::CommunicationRobot11(char key, R11CommunicationType type) : CommunicationRobotPiezas(key) {
	this->key = key;
	char espera12Key = CommunicationRobotPiezas::getAltKey(key);
	/* Create semaphores by type, just those needed*/
	if (DSEM_ENABLED) {
		switch (type) {
			case ROBOT5:
			case AGV:
				this->semRobot = ipc::Semaphore::get(getSemRobot11FileSignal(), key);
				break;
			case ROBOT11:
				this->semRobot = ipc::Semaphore::get(getSemRobot11FileWait(), key);
				this->semEsperaRobot12 = ipc::Semaphore::get(getSemRobot11FileWait(), espera12Key);
				break;
			case ROBOT12:
				this->semEsperaRobot12 = ipc::Semaphore::get(getSemRobot11FileSignal(), espera12Key);
				break;
		}
	} else {
		this->semRobot = ipc::Semaphore::get(ROBOT11_SEM_PATH, key);
		this->semEsperaRobot12 = ipc::Semaphore::get(ROBOT11_SEM_PATH, espera12Key);
	}

	this->shMemEstado = ipc::SharedMemoryInterface<EstadoRobotPiezas>::get(ROBOT11_SHMEM_PATH, key, DSM_ENABLED ? ((key == ROBOT11_SHMEM_KEY_IZQ)? DSMID_EROBOT11_IZQ : DSMID_EROBOT11_DER) : 0);
}

void CommunicationRobot11::create(char key, R11CommunicationType type) {
	char espera12Key = CommunicationRobotPiezas::getAltKey(key);
	/* Create semaphores by type, just those needed*/
	if (DSEM_ENABLED) {
		switch (type) {
			case ROBOT5:
			case AGV:
				ipc::Semaphore::createNonExclusive(getSemRobot11FileSignal(), key).initialize(0);
				break;
			case ROBOT11:
				ipc::Semaphore::createNonExclusive(getSemRobot11FileWait(), key).initialize(0);
				ipc::Semaphore::createNonExclusive(getSemRobot11FileWait(), espera12Key).initialize(0);
				break;
			case ROBOT12:
				ipc::Semaphore::createNonExclusive(getSemRobot11FileSignal(), espera12Key).initialize(0);
				break;
		}
	} else {
		ipc::Semaphore::createNonExclusive(ROBOT11_SEM_PATH, key);
		ipc::Semaphore::createNonExclusive(ROBOT11_SEM_PATH, espera12Key);
	}

	ipc::SharedMemoryInterface<EstadoRobotPiezas> tmpMem = ipc::SharedMemoryInterface<EstadoRobotPiezas>::createNonExclusive(ROBOT11_SHMEM_PATH, key);
	if (!DSM_ENABLED){
		tmpMem.lock();
		tmpMem.write(ROBOT_INACTIVO);
		tmpMem.unlock();
	}
}

void CommunicationRobot11::destroy(char key) {
	char espera12Key = CommunicationRobotPiezas::getAltKey(key);
	/* Destroy everything if needed */
	ipc::Semaphore::destroyNonExclusive(getSemRobot11FileSignal(), key);
	ipc::Semaphore::destroyNonExclusive(getSemRobot11FileSignal(), espera12Key);
	ipc::Semaphore::destroyNonExclusive(getSemRobot11FileWait(), key);
	ipc::Semaphore::destroyNonExclusive(getSemRobot11FileWait(), espera12Key);
	ipc::Semaphore::destroyNonExclusive(ROBOT11_SEM_PATH, key);
	ipc::Semaphore::destroyNonExclusive(ROBOT11_SEM_PATH, espera12Key);

	ipc::SharedMemoryInterface<EstadoRobotPiezas>::destroy(ROBOT11_SHMEM_PATH, key);
}

void CommunicationRobot11::esperarRobot12() {
	this->semEsperaRobot12.wait();
}

void CommunicationRobot11::robot12EstaListo() {
	this->semEsperaRobot12.signal();
}

std::string CommunicationRobot11::getNombre() {
	return "robot 11";
}

CommunicationRobot11::~CommunicationRobot11() {
}

std::string CommunicationRobot11::getSemRobot11FileWait() {
	return ROBOT11_SEM_PATH+"wait";
}

std::string CommunicationRobot11::getSemRobot11FileSignal() {
	return ROBOT11_SEM_PATH+"signal";
}

/* Este metodo dummy es por simetria */
char CommunicationRobot11::getSemControlRobot11Key(char key) {
	return key;
}

std::string CommunicationRobot11::getSemControlName() {
	return "robot11Control";
}

std::string CommunicationRobot11::getSemEspera12Name() {
	return "robot11Espera12";

}

char CommunicationRobot11::getSemEsperaRobot12Key(char key) {
	return CommunicationRobotPiezas::getAltKey(key);
}

/* namespace middleware */

}

